package general.art;

import general.database.SQLiteInterface;
import general.database.info.NodeInfo;
import general.exceptions.NodeNotFoundException;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

/**
 * This is the Node class that holds information about a single node.
 * 
 * @author Lance, hood
 * 
 */
public class Node extends art.applications.seek.Node<NodeTypes> implements
		Comparable<Node> {

	private static Map<Integer, Node> SET_OF_ALL_NODES = new HashMap<Integer, Node>();

	public static Node FIND_NODE(int key) throws InstantiationException,
			IllegalAccessException, ClassNotFoundException, SQLException,
			NodeNotFoundException {

		if (!SET_OF_ALL_NODES.containsKey(key)) {
			SET_OF_ALL_NODES.put(key, PULL_NODE_FROM_DATA_BASE(key));
		}

		return SET_OF_ALL_NODES.get(key);

	}

	private static Node PULL_NODE_FROM_DATA_BASE(int key)
			throws InstantiationException, IllegalAccessException,
			ClassNotFoundException, SQLException, NodeNotFoundException {

		SQLiteInterface dataBaseInterface = new SQLiteInterface();
		return new Node(dataBaseInterface.getNodeInfo(key));
	}

	/**
	 * Used when a Node does not have a key. IE, before it has been ever added
	 * to the database.
	 */
	public static final int NOKEY = -1;

	/** needed to shut up csv check. */
	private static final long serialVersionUID = 1L;

	/**
	 * Holds the key for the node.
	 */
	private int mKey;

	/**
	 * Holds the name of the node.
	 */
	private String mName;

	/**
	 * Holds the type of the node.
	 */
	private NodeTypes mType;

	/**
	 * Constructor for a Node.
	 * 
	 * @param key
	 *            The key of this node.
	 * @param name
	 *            The name of this node.
	 * @param type
	 *            The type of this node.
	 */
	private Node(final int key, final String name, final NodeTypes type) {
		mKey = key;
		mName = name;
		mType = type;
	}

	/**
	 * Constructor for a node takes a Nodeinfo parameter, Nodeinfo is a key
	 * String name NodeTypes for a node.
	 * 
	 * @param i
	 */
	private Node(NodeInfo i) {

		mKey = i.key;
		mName = i.lemma;
		mType = i.type;

	}

	/**
	 * @return - Returns the nodes key.
	 */
	public int getKey() {
		return mKey;
	}

	/**
	 * @return - Returns the name of the node.
	 */
	public String getName() {
		return mName;
	}

	/**
	 * @return - The type of node.
	 */
	public NodeTypes type() {
		return mType;
	}

	/**
	 * @param n
	 *            The node to compare to.
	 * @return True or false depending on whether the object is equal to this
	 *         node.
	 */
	public boolean equals(final Node n) {

		if (n.getKey() != this.getKey()) {
			return false;
		}

		return true;
	}

	/**
	 * TODO for check style.
	 * 
	 * @return returns the key as a hash code ?????
	 */
	public int hashCode() {
		return mKey;
	}

	/**
	 * Gets the name of this node.
	 * 
	 * @return gets the name of the node
	 */
	public String getString() {
		return mName;
	}

	/**
	 * @param otherNode
	 *            the other node that the node has the compare against
	 * @return weather they equal or one is less than the other
	 */
	public int compareTo(final Node otherNode) {

		if (this.toString().compareTo(otherNode.getString()) > 0) {

			return 1;

		} else if (this.toString().compareTo(otherNode.getString()) < 0) {

			return -1;

		} else {

			return 0;
		}
	}
	
	public String toString()
	{
		return this.mKey + ", " + this.mName;
	}

	@Override
	public boolean integrity() {
		// TODO Auto-generated method stub
		return true;
	}

}
